home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / util / arc / xadmaster.lha / xad / Developer / Sources / clients / Tar.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-31  |  6.1 KB  |  234 lines

  1. #ifndef XADMASTER_TAR_C
  2. #define XADMASTER_TAR_C
  3.  
  4. /* Programmheader
  5.  
  6.     Name:        Tar.c
  7.     Main:        xadmaster
  8.     Versionstring:    $VER: Tar.c 1.4 (11.08.2000)
  9.     Author:        SDI
  10.     Distribution:    Freeware
  11.     Description:    Tar file archiver client
  12.  
  13.  1.0   07.09.98 : first version
  14.  1.1   29.06.99 : now uses master free stuff
  15.  1.2   29.08.99 : now uses xfi_DataPos
  16.  1.3   15.09.99 : also strips / from TF_DIR entries
  17.  1.4   11.08.00 : cleaner design
  18. */
  19.  
  20. #include <proto/xadmaster.h>
  21. #include <dos/dos.h>
  22. #include "SDI_compiler.h"
  23. #define SDI_TO_ANSI
  24. #include "SDI_ASM_STD_protos.h"
  25.  
  26. #ifndef XADMASTERFILE
  27. #define Tar_Client        FirstClient
  28. #define NEXTCLIENT        0
  29. #define XADMASTERVERSION    8
  30. UBYTE version[] = "$VER: Tar 1.4 (11.08.2000)";
  31. #endif
  32. #define TAR_VERSION        1
  33. #define TAR_REVISION        4
  34.  
  35. struct TarHeader
  36. {                /* byte offset */
  37.   UBYTE th_Name[100];        /*   0 */
  38.   UBYTE th_Mode[8];        /* 100 */
  39.   UBYTE th_UserID[8];        /* 108 */
  40.   UBYTE th_GroupID[8];        /* 116 */
  41.   UBYTE th_Size[12];        /* 124 */
  42.   UBYTE th_MTime[12];        /* 136 */
  43.   UBYTE th_Checksum[8];     /* 148 */
  44.   UBYTE th_Typeflag;        /* 156 */
  45.   UBYTE th_LinkName[100];    /* 157 */
  46.   UBYTE th_Magic[6];        /* 257 */
  47.   UBYTE th_Version[2];        /* 263 */
  48.   UBYTE th_UserName[32];    /* 265 */
  49.   UBYTE th_GroupName[32];    /* 297 */
  50.   UBYTE th_DevMajor[8];     /* 329 */
  51.   UBYTE th_DevMinor[8];     /* 337 */
  52.   UBYTE th_Prefix[155];     /* 345 */
  53.   UBYTE th_Pad[12];        /* 500 */
  54. };
  55.  
  56. /* Values used in Typeflag field.  */
  57. #define TF_FILE     '0'  /* Regular file */
  58. #define TF_AFILE    '\0' /* Regular file */
  59. #define TF_LINK     '1'  /* Link */
  60. #define TF_SYM        '2'  /* Reserved - but GNU tar uses this for links... */
  61. #define TF_CHAR     '3'  /* Character special */
  62. #define TF_BLOCK    '4'  /* Block special */
  63. #define TF_DIR        '5'  /* Drawer */
  64. #define TF_FIFO     '6'  /* FIFO special */
  65. #define TF_CONT     '7'  /* Reserved */
  66.  
  67. static ULONG octtonum(STRPTR oct, LONG width, LONG *ok)
  68. {
  69.   ULONG i = 0;
  70.  
  71.   while(width-- && *oct == ' ')
  72.     ++oct;
  73.  
  74.   if(!*oct)
  75.     *ok = 0;
  76.   else
  77.   {
  78.     while(width-- && *oct >= '0' && *oct <= '7')
  79.      i = (i*8)+*(oct++)-'0';
  80.  
  81.     if(width > 0 && *oct)    /* an error, set error flag */
  82.       *ok = 0;
  83.   }
  84.  
  85.   return i;
  86. }
  87.  
  88. static BOOL checktarsum(struct TarHeader *th)
  89. {
  90.   LONG sc, i;
  91.   ULONG uc, checks;
  92.   
  93.   i = 1;
  94.   checks = octtonum(th->th_Checksum, 8, &i);
  95.   if(!i)
  96.     return 0;
  97.  
  98.   for(i = sc = uc = 0; i < 512; ++i)
  99.   {
  100.     sc += ((BYTE *) th)[i];
  101.     uc += ((UBYTE *) th)[i];
  102.   }
  103.   
  104.   for(i = 148; i < 156; ++i)
  105.   {
  106.     sc -= ((BYTE *) th)[i];
  107.     uc -= ((UBYTE *) th)[i];
  108.   }
  109.   sc += 8 * ' ';
  110.   uc += 8 * ' ';
  111.   
  112.   if(checks != uc && checks != (ULONG) sc)
  113.     return 0;
  114.   return 1;
  115. }
  116.  
  117. ASM(BOOL) Tar_RecogData(REG(d0, ULONG size), REG(a0, STRPTR data),
  118. REG(a6, struct xadMasterBase *xadMasterBase))
  119. {
  120.   if(data[0] > 0x1F && checktarsum((struct TarHeader *) data))
  121.     return 1;
  122.   else
  123.     return 0;
  124. }
  125.  
  126. ASM(LONG) Tar_GetInfo(REG(a0, struct xadArchiveInfo *ai),
  127. REG(a6, struct xadMasterBase *xadMasterBase))
  128. {
  129.   struct TarHeader th;
  130.   struct xadFileInfo *fi = 0, *fi2;
  131.   LONG err = 0, size, ok, a, b, d, i, pos, num = 1;
  132.  
  133.   while(!err && ai->xai_InPos < ai->xai_InSize && !(err = xadHookAccess(XADAC_READ, sizeof(struct TarHeader), &th, ai)))
  134.   {
  135.     if(!th.th_Name[0])
  136.       break;
  137.     ok = checktarsum(&th); /* check checksum and init ok */
  138.     size = octtonum(th.th_Size, 12, &ok);
  139.  
  140.     pos = ai->xai_InPos;
  141.     if(ok && (th.th_Typeflag == TF_FILE || th.th_Typeflag == TF_AFILE) &&
  142.     (err = xadHookAccess(XADAC_INPUTSEEK, (size+511)&~511, 0, ai)))
  143.       break;
  144.     if(ok && (th.th_Typeflag == TF_FILE || th.th_Typeflag == TF_AFILE ||
  145.     th.th_Typeflag == TF_DIR || th.th_Typeflag == TF_SYM ||
  146.     th.th_Typeflag == TF_LINK))
  147.     {
  148.       a = strlen(th.th_Name) + 1;
  149.       if(th.th_Name[a-2] == '/')
  150.       {
  151.     if(th.th_Typeflag == TF_AFILE || th.th_Typeflag == TF_FILE || th.th_Typeflag == TF_DIR)
  152.     {
  153.       th.th_Name[--a-1] == 0;
  154.           th.th_Typeflag = TF_DIR;
  155.         }
  156.       }
  157.       
  158.       b = th.th_LinkName[0] ? 1 + strlen(th.th_LinkName) : 0;
  159.       i = th.th_UserName[0] ? 1 + strlen(th.th_UserName) : 0;
  160.       d = th.th_GroupName[0] ? 1 + strlen(th.th_GroupName) : 0;
  161.       
  162.       if(!(fi2 = (struct xadFileInfo *) xadAllocObject(XADOBJ_FILEINFO,
  163.       XAD_OBJNAMESIZE, a+b+i+d, TAG_DONE)))
  164.         err = XADERR_NOMEMORY;
  165.       else
  166.       {
  167.         fi2->xfi_DataPos = pos;
  168.         fi2->xfi_Flags = XADFIF_SEEKDATAPOS;
  169.     if(th.th_Typeflag == TF_LINK || th.th_Typeflag == TF_SYM)
  170.       fi2->xfi_Flags |= XADFIF_LINK;
  171.     else if(th.th_Typeflag == TF_DIR)
  172.     {
  173.       fi2->xfi_Flags |= XADFIF_DIRECTORY;
  174.       size = 0;
  175.     }
  176.         fi2->xfi_CrunchSize = fi2->xfi_Size = size;
  177.         xadCopyMem(th.th_Name, fi2->xfi_FileName, a-1);
  178.         if(b)
  179.         {
  180.           fi2->xfi_LinkName = fi2->xfi_FileName + a;
  181.           xadCopyMem(th.th_LinkName, fi2->xfi_LinkName, b-1);
  182.         }
  183.         if(i)
  184.         {
  185.           fi2->xfi_UserName = fi2->xfi_FileName + a + b;
  186.           xadCopyMem(th.th_UserName, fi2->xfi_UserName, i-1);
  187.         }
  188.         if(d)
  189.         {
  190.           fi2->xfi_GroupName = fi2->xfi_FileName + a + b + i;
  191.           xadCopyMem(th.th_GroupName, fi2->xfi_GroupName, d-1);
  192.         }
  193.         fi2->xfi_OwnerUID = octtonum(th.th_UserID, 8, &ok);
  194.         fi2->xfi_OwnerGID = octtonum(th.th_GroupID, 8, &ok);
  195.  
  196.         xadConvertProtection(XAD_PROTUNIX, octtonum(th.th_Mode, 8, &ok), XAD_GETPROTAMIGA,
  197.         &fi2->xfi_Protection, TAG_DONE);
  198.  
  199.         xadConvertDates(XAD_DATEUNIX, octtonum(th.th_MTime, 12, &ok),
  200.         XAD_MAKELOCALDATE, 1, XAD_GETDATEXADDATE, &fi2->xfi_Date, TAG_DONE);
  201.  
  202.         fi2->xfi_EntryNumber = num++;
  203.         if(fi)
  204.           fi->xfi_Next = fi2;
  205.         else
  206.           ai->xai_FileInfo = fi2;
  207.         fi = fi2;
  208.       }
  209.     }
  210.   }
  211.  
  212.   if(err)
  213.   {
  214.     ai->xai_Flags |= XADAIF_FILECORRUPT;
  215.     ai->xai_LastError = err;
  216.   }
  217.  
  218.   return (ai->xai_FileInfo ? 0 : err);
  219. }
  220.  
  221. ASM(LONG) Tar_UnArchive(REG(a0, struct xadArchiveInfo *ai),
  222. REG(a6, struct xadMasterBase *xadMasterBase))
  223. {
  224.   return xadHookAccess(XADAC_COPY, ai->xai_CurFile->xfi_Size, 0, ai);
  225. }
  226.  
  227. const struct xadClient Tar_Client = {
  228. NEXTCLIENT, XADCLIENT_VERSION, XADMASTERVERSION, TAR_VERSION, TAR_REVISION,
  229. 512, XADCF_FILEARCHIVER|XADCF_FREEFILEINFO, XADCID_TAR, "Tar",
  230. (BOOL (*)()) Tar_RecogData, (LONG (*)()) Tar_GetInfo,
  231. (LONG (*)()) Tar_UnArchive, 0};
  232.  
  233. #endif /* XADASTER_TAR_C */
  234.